package de.lulusoft.anothertorrent.core.rtorrent;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;

import de.lulusoft.anothertorrent.core.AnotherTorrentCore;

public class TorrentCommands implements Serializable {

	private static final long serialVersionUID = 3824551657853553619L;
	
	private static final String FILENAME = "torrentCommands";
	private static TorrentCommands instance = null;

	private ArrayList<TorrentCommand> commands = null;
	
	public static TorrentCommands getINSTANCE()
	{
		if (instance == null)
			instance = load();
		return instance;
	}
	
	private TorrentCommands()
	{
		commands = new ArrayList<TorrentCommand>();
	}
	
	/**
	 * Adds a new TorrentCommand to this list and saves it to disk.
	 * @param name
	 * @param cmd 
	 * @return the newly created TorrentCommand
	 */
	public TorrentCommand addCommand(String name, String cmd)
	{
		TorrentCommand tc = new TorrentCommand(name, cmd, generateTorrentCommandId(this)); 
		commands.add(tc);
		save();
		return tc;
	}
	
	private static int generateTorrentCommandId(TorrentCommands tcs) {
		int id = 1;
		boolean inUse = true;
		while (inUse) {
			inUse = false;
			for (TorrentCommand tc : tcs.getCommands()) {
				if (tc.getId() == id) {
					id++;
					inUse = true;
					break;
				}
			}
		}
		return id;
	}
	
	public ArrayList<TorrentCommand> getCommands()
	{
		return commands;
	}
	
	public TorrentCommand getCommandById(int id) {
		for (TorrentCommand tc : commands) {
			if (tc.getId() == id) {
				return tc;
			}
		}
		return null;
	}
	
	public void save()
	{
		FileOutputStream fOut=null;
		ObjectOutputStream oOut=null;
   
		try
		{
			fOut= new FileOutputStream(AnotherTorrentCore.getDefault().getStateLocation()
					+ "/" + FILENAME);
			oOut = new ObjectOutputStream(fOut);
			oOut.writeObject(this);
			
		}catch(IOException e){
			e.printStackTrace(); 
		}finally
		{
			try 
			{
			    oOut.flush();
			    oOut.close();
			    fOut.close();
			} catch (IOException e1) 
			{
				e1.printStackTrace();
			}
		}
	}
	
	private static TorrentCommands load()
	{
		String filename = AnotherTorrentCore.getDefault().getStateLocation()
		+ "/" + FILENAME;
		if (new File(filename).exists())
		{
			FileInputStream fIn = null;
			ObjectInputStream oIn = null;
	   
			try
			{
				fIn= new FileInputStream(filename);
				oIn = new ObjectInputStream(fIn);
				TorrentCommands mgr = (TorrentCommands) oIn.readObject();
				// Backwards compatibility: Check for TorrentCommand.id
				for (TorrentCommand tc : mgr.getCommands()) {
					if (tc.getId() == 0)
						tc.setId(generateTorrentCommandId(mgr));
				}
				return mgr;
			}catch(IOException e)
			{
				e.printStackTrace(); 
			}catch(ClassNotFoundException e)
			{
				e.printStackTrace(); 
			}finally
			{
				try 
				{
					oIn.close();
					fIn.close();
				} catch (IOException e1) 
				{
					e1.printStackTrace();
				}
			}
		}
		return new TorrentCommands();
	}
}
